﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML dir=ltr XMLNS:MSHelp = "http://msdn.microsoft.com/mshelp" xmlns:ddue = 
"http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink = 
"http://www.w3.org/1999/xlink" xmlns:tool = "http://www.microsoft.com/tooltip"
XMLNS:[default] http://ddue.schemas.microsoft.com/authoring/2003/5 =
"http://ddue.schemas.microsoft.com/authoring/2003/5"><HEAD>
  <TITLE>Request Response Sample</TITLE>
  <META content="text/html; CHARSET=utf-8" http-equiv=Content-Type></META>
  <META name=save content=history></META>
  <LINK rel=stylesheet type=text/css
  href="../../../CommonFiles/Classic.css"></LINK>

  <META name=GENERATOR content="MSHTML 8.00.6001.18783">
    <style type="text/css">
      .style1 {
      font-family: monospace;
      font-size: 100%;
      color: #000000;
      }
      .style2 {
      font-family: monospace;
      font-size: small;
      color: #000000;
      }
      </style>
  </HEAD>
<BODY>
  <DIV id=header>
    <TABLE id=topTable width="100%">
      <TBODY>
        <TR id=headerTableRow1>
          <TD align=left>
            <SPAN id=runningHeaderText></SPAN>
          </TD>
        </TR>
        <TR id=headerTableRow2>
          <TD align=left>
              <SPAN id=nsrTitle>Request/Response Sample</SPAN>
          </TD>
        </TR>
        <TR id=headerTableRow3>
          <TD></TD>
        </TR>
      </TBODY>
    </TABLE>
  </DIV>
  <DIV id=mainSection>
    <DIV id=mainBody>
      <P>
          This sample demonstrates how to use the Windows Azure Service Bus and 
          the Request/Response functionality.
      </P>
      <P>
          The sample shows simple clients and servers communicating via two Service Bus 
          queues. The SampleManager first prompts for service namespace credentials. These 
          are used to authenticate with the Access Control service, and acquire an access 
          token that proves to the Service Bus infrastructure that the client is 
          authorized to access the queue. The SampleManager creates two queues, one for
          requests and one for responses. It then creates one or more clients and servers.
          Each client sends messages on the request queue and asynchronously receives a
          message on the response queue. The servers read a message from the request queue
          and sends a message on the response queue.</P>
      <P>
          Many application scenarios involve two-way communications in which a sender
          would like to receive and correlate responses for the messages that it sends.
          This is supported in Service Bus through the use of the properties SessionId and
          ReplyToSessionId on a message. Consider a pattern involving several clients that
          are sending messages and expect responses for these messages to be directed back
          to them. To enable this pattern, a given client, say client “ABC”, would set
          ReplyToSessionId=”ABC” on any messages it sends and also use MessageSession on
          a reply Topic/Subscription or Queue to listen for messages where SessionId=ABC.
          To complete the pattern, any processor of the message would set
          SessionId=ReplyToSessionId once a message has been processed.
      </P>
      <H2 class=heading>Prerequisites</H2>
      <DIV id=sectionSection0 class=section>
        <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <P xmlns="">
            If you haven't already done so, please read the release notes
            document that explains how to sign up for a Windows Azure
            account and how to configure your environment.
          </P>
        </content>
      </DIV>
      <H2 class=heading>SampleManager</H2>
      <DIV id=sectionSection1 class="section">
        <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <P xmlns="">
              The SampleManager gets user credentials and creates a NamespaceManager 
              (namespaceManager). This entity holds the credentials and is used for all 
              messaging management operations. The namespaceClient is used to create queues 
              for communication between the client(s) and server(s). The SampleManager then 
              creates client(s) and server(s), passing the user credentials to each.</P>
          <p xmlns="">
            The following code prompts for the issuer credentials and then constructs the
            listening URI using that information. The static <code>
              ServiceBusEnvironment.CreateServiceUri
            </code> function is provided to help
            construct the URI with the correct format and domain name. It is strongly
            recommended that you use this function instead of building the URI from scratch
            because the URI construction logic and format might change in future releases.            
            </code>
          </p>
          <DIV class=code xmlns="">
            <SPAN codeLanguage="CSharp">
              <TABLE cellSpacing=0 cellPadding=0 width="100%">
                <TBODY>
                  <TR>
                    <TH>C#&nbsp;</TH>
                  </TR>
                  <TR>
                    <TD colSpan=2>
                      <PRE>
                        static void Main(string[] args)
                        {
                            // Setup:
                            ParseArgs(args);
                            GetUserCredentials();
                            CreateNamespaceClient();

                            // Create queues:
                            Console.WriteLine("\nCreating Queues...");
                            QueueDescription requestQueue = CreateQueue(requestQueuePath, false);
                            Console.WriteLine(
                                "Created {0}, Queue.RequiresSession = {1}", requestQueue.Path, requestQueue.RequiresSession);
                            QueueDescription responseQueue = CreateQueue(responseQueuePath, true);
                            Console.WriteLine(
                                "Created {0}, Queue.RequiresSession = {1}", responseQueue.Path, responseQueue.RequiresSession);

                            ...
                        }

                        // Create the management entities (queue)
                        static void CreateNamespaceClient()
                        {
                            TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                                ServiceBusIssuerName, ServiceBusIssuerKey);

                            Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceBusNamespace, string.Empty);
                            namespaceManager = new NamespaceManager(uri, tokenProvider);
                        }

                        static QueueDescription CreateQueue(string queuePath, bool session)
                        {
                            QueueDescription queueDescription = new QueueDescription() { RequiresSession = session, Path = queuePath};

                            // Delete the queue if it already exists
                            if (namespaceManager.QueueExists(queuePath))
                            {
                                namespaceManager.DeleteQueue(queuePath);
                            }

                            return namespaceManager.CreateQueue(queueDescription);
                        }
                      </PRE>
                    </TD>
                  </TR>
                </TBODY>
              </TABLE>
            </SPAN>
          </DIV>
          <DIV class=code xmlns="">
          </DIV>
          <p xmlns="">
              &nbsp;The SampleManager then creates client and server processes and starts them.<BR>
              <BR>
          </p>
          <DIV class=code xmlns="">
            <SPAN codeLanguage="CSharp">
              <TABLE cellSpacing="0" cellPadding="0" width="100%">
                <TBODY>
                  <TR>
                    <TH>C#&nbsp;</TH>
                  </TR>
                  <TR>
                    <TD colSpan=2>
                      <PRE class="style1">
                        static void Main(string[] args)
                        {
                            ...

                            // Start clients and servers:
                            Console.WriteLine("\nLaunching clients and servers...");
                            StartClients();
                            StartServers();

                            Console.WriteLine("\nPress [Enter] to exit.");
                            Console.ReadLine();

                            ...
                        }

                        static void StartClients()
                        {
                            ProcessStartInfo startInfo = new ProcessStartInfo();
                            startInfo.FileName = "RequestResponseSampleClient.exe";
                            for (int i = 0; i < numClients; ++i)
                            {
                                startInfo.Arguments = CreateArgs(i.ToString());
                                Process process = Process.Start(startInfo);
                                clientProcs.Add(process);
                            }
                            Thread.Sleep(500);
                            ArrangeWindows();
                        }

                        static void StartServers()
                        {
                            ProcessStartInfo startInfo = new ProcessStartInfo();
                            startInfo.FileName = "RequestResponseSampleServer.exe";
                            startInfo.Arguments = CreateArgs();
                            for (int i = 0; i < numServers; ++i)
                            {
                                Process process = Process.Start(startInfo);
                                serverProcs.Add(process);
                            }
                            Thread.Sleep(500);
                            ArrangeWindows();
                        }
                      </PRE>
                    </TD>
                  </TR>
                </TBODY>
              </TABLE>
            </SPAN>
          </DIV>
          <P xmlns="">
              Finally, the SampleManager cleans up by deleting the queues and stopping the 
              clients and servers if necessary.</P>
          <div class="code" xmlns="">
            <span codelanguage="CSharp">
              <table cellpadding="0" cellspacing="0" width="100%">
                <tr>
                  <th>
                    C#&nbsp;
                  </th>
                </tr>
                <tr>
                  <td colspan="2">
                    <pre class="style1">
                    static void Main(string[] args)
                    {
                        ...

                        // Cleanup:
                        namespaceClient.DeleteQueue(requestQueue.Path);
                        namespaceClient.DeleteQueue(responseQueue.Path);
                        StopClients();
                        StopServers();  
                    }

                    static void StopClients()
                    {
                        foreach (Process proc in clientProcs)
                        {
                            proc.CloseMainWindow();
                        }
                    }

                    static void StopServers()
                    {
                        foreach (Process proc in serverProcs)
                        {
                            proc.CloseMainWindow();
                        }
                    }                        
                    </pre>
                  </td>
                </tr>
              </table>
            </span>
          </div>
      <H2 class=heading>Client</H2>
      <DIV id=sectionSection3 class="section">
        <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <P xmlns="">
              The Client gets user credentials as parameters from SampleManager and creates a 
              MessagingFactory (messagingFactory). This entity holds the credentials and is 
              used for all messaging runtime operations, such as opening a QueueClient to send 
              messages to the queues. The Client then creates QueueClients to the request and 
              response queues.  Messages are sent to the server on the request queue and
              responses are processed asynchonously by calling <code>responseClient.BeginReceive()</code>.</P>
          <DIV class=code xmlns="">
            <SPAN codeLanguage="CSharp">
              <TABLE cellSpacing=0 cellPadding=0 width="100%">
                <TBODY>
                  <TR>
                    <TH>C#&nbsp;</TH>
                  </TR>
                  <TR>
                    <TD>
                      <PRE>
                        static void Main(string[] args)
                        {
                            ParseArgs(args);
                            Console.Title = "Client";

                            // Send request messages to request queue
                            QueueClient requestClient = CreateQueueClient(SampleManager.RequestQueuePath);
                            QueueClient responseClient = CreateQueueClient(SampleManager.ResponseQueuePath);
                            MessageSession session = responseClient.AcceptMessageSession(ClientId);
                            Console.WriteLine("Preparing to send request messages to {0}...", requestClient.Path);

                            SendMessages(requestClient, responseClient, session);

                            ...
                        }

                        // Create the runtime entities (queue client)
                        static QueueClient CreateQueueClient(string queuePath)
                        {
                            TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                                ServiceBusIssuerName, ServiceBusIssuerKey);

                            Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceBusNamespace, string.Empty);
                            MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);

                            return messagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete);
                        }

                        static void SendMessages(QueueClient requestClient, QueueClient responseClient, MessageSession session)
                        {
                            // Send request messages to queue:
                            Console.WriteLine("Sending request messages to queue {0}", requestClient.Path);
                            Console.WriteLine("Receiving response messages on queue {0}", responseClient.Path);

                            for (int i = 0; i < SampleManager.NumMessages; ++i)
                            {
                                // send request message
                                BrokeredMessage message = new BrokeredMessage { ReplyToSessionId = ClientId, MessageId = i.ToString() };
                
                                requestClient.Send(message);
                                SampleManager.OutputMessageInfo("REQUEST: ", message);

                                // start asynchronous receive operation
                                session.BeginReceive(TimeSpan.FromSeconds(ResponseMessageTimeout), ProcessResponse, session);
                            }


                            Console.WriteLine();
                        }

                        static void ProcessResponse(IAsyncResult result)
                        {
                            MessageSession session = result.AsyncState as MessageSession;
                            BrokeredMessage message = session.EndReceive(result);

                            if (message == null)
                            {
                                Console.WriteLine("ERROR: Message Receive Timeout.");
                            }
                            else
                            {
                                SampleManager.OutputMessageInfo("RESPONSE: ", message);
                            }
                        }
                      </PRE>
                    </TD>
                  </TR>
                </TBODY>
              </TABLE>
            </SPAN>
          </DIV>
        </DIV>
      <H2 class=heading>Server</H2>
      <DIV id=sectionSection2 class=section>
        <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <P xmlns="">
              The Server also gets user credentials as parameters from SampleManager and 
              creates a MessagingFactory (messagingFactory). This entity holds the credentials 
              and is used for all messaging runtime operations, such as opening a QueueClient to 
              receive messages from the queues. The Server then creates QueueClients to the request and 
              response queues and starts receiving and responding to request messages:</P>
          <DIV class=code xmlns="">
            <SPAN codeLanguage="CSharp">
              <TABLE cellSpacing=0 cellPadding=0 width="100%">
                <TBODY>
                  <TR>
                    <TH>C#&nbsp;</TH>
                  </TR>
                  <TR>
                    <TD colSpan=2>
                      <PRE class="style1">
                        static void Main(string[] args)
                        {
                            ParseArgs(args);

                            // Receive request messages from request queue
                            Console.Title = "Server";
                            QueueClient requestClient = CreateQueueClient(SampleManager.RequestQueuePath);
                            QueueClient responseClient = CreateQueueClient(SampleManager.ResponseQueuePath);
                            Console.WriteLine("Ready to receive messages from {0}...", requestClient.Path);

                            ReceiveMessages(requestClient, responseClient);
                        
                            ...
                        }

                        static QueueClient CreateQueueClient(string queuePath)
                        {
                            TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
                                ServiceBusIssuerName, ServiceBusIssuerKey);

                            Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceBusNamespace, string.Empty);
                            MessagingFactory messagingFactory = MessagingFactory.Create(uri, tokenProvider);

                            return messagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete);
                        }

                        static void ReceiveMessages(QueueClient requestClient, QueueClient responseClient)
                        {
                            // Read messages from queue until queue is empty:
                            Console.WriteLine("Reading messages from queue {0}", requestClient.Path);

                            BrokeredMessage request;
                            while ((request = requestClient.Receive(TimeSpan.FromSeconds(ReceiveMessageTimeout))) != null)
                            {
                                SampleManager.OutputMessageInfo("REQUEST: ", request);

                                BrokeredMessage response = new BrokeredMessage
                                    { SessionId = request.ReplyToSessionId, MessageId = request.MessageId };

                                responseClient.Send(response);
                                SampleManager.OutputMessageInfo("RESPONSE: ", response);
                            }
                        }
                      </PRE>
                    </TD>
                  </TR>
                </TBODY>
              </TABLE>
            </SPAN>
          </DIV>
        </content>
      </DIV>
    </DIV>
    <H2 class=heading>Running the Sample</H2>
    <DIV id=DIV1 class=section>
      <content
xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
        <P xmlns="">
            To run the sample, build the solution in Visual Studio or from the command line, 
            then run the resulting SampleManager.exe executable file. The program will 
            prompt for your service namespace and the issuer credentials. For the 
            issuer secret, be sure to use the &quot;Default Issuer Key&quot; value (typically &quot;owner&quot;) 
            from the portal, rather than one of the management keys.
        </P>
        <P xmlns="">
          <B>Expected Output - SampleManager </B>
        </P>
        <DIV class=code xmlns="">
          <SPAN codeLanguage="other">
            <TABLE cellSpacing=0 cellPadding=0 width="100%">
              <TBODY>
                <TR>
                  <TD>
                    <PRE class="style2">
                         Please provide the namespace to use:
                        &lt;service namespace&gt;
                        Please provide the Issuer name to use:
                        &lt;issuer name&gt;
                        Please provide the Issuer key to use:
                        &lt;issuer key&gt;

                        Creating Queues...
                        Created RequestQueue, Queue.RequiresSession = False
                        Created ResponseQueue, Queue.RequiresSession = True

                        Launching clients and servers...

                        Press [Enter] to exit.
                    </PRE>
                  </TD>
                </TR>
              </TBODY>
            </TABLE>
          </SPAN>
        </DIV>
        <P xmlns="">
          <B>Expected Output - Client</B>
        </P>
        <DIV class=code xmlns="">
          <SPAN codeLanguage="other">
            <TABLE cellSpacing=0 cellPadding=0 width="100%">
              <TBODY>
                <TR>
                  <TD colSpan=2>
                    <PRE class="style2">
                        Preparing to send request messages to RequestQueue...
                        Sending request messages to queue RequestQueue
                        Receiving response messages on queue ResponseQueue
                        REQUEST: 0 - Client 0.
                        REQUEST: 1 - Client 0.
                        REQUEST: 2 - Client 0.
                        REQUEST: 3 - Client 0.
                        REQUEST: 4 - Client 0.
                        REQUEST: 5 - Client 0.
                        REQUEST: 6 - Client 0.
                        REQUEST: 7 - Client 0.
                        REQUEST: 8 - Client 0.
                        REQUEST: 9 - Client 0.


                        Client finished sending requests.
                        RESPONSE: 0 - Client 0.
                        RESPONSE: 1 - Client 0.
                        RESPONSE: 2 - Client 0.
                        RESPONSE: 3 - Client 0.
                        RESPONSE: 4 - Client 0.
                        RESPONSE: 5 - Client 0.
                        RESPONSE: 6 - Client 0.
                        RESPONSE: 7 - Client 0.
                        RESPONSE: 8 - Client 0.
                        RESPONSE: 9 - Client 0.
                    </PRE>
                  </TD>
                </TR>
              </TBODY>
            </TABLE>
          </SPAN>
        </DIV>
        <P xmlns="">
          <B>Expected Output - Server</B>
        </P>
        <DIV class=code xmlns="">
          <SPAN codeLanguage="other">
            <TABLE cellSpacing=0 cellPadding=0 width="100%">
              <TBODY>
                <TR>
                  <TD colSpan=2>
                    <PRE>
                        Ready to receive messages from RequestQueue...
                        Reading messages from queue RequestQueue
                        REQUEST: 0 - Client 2.
                        RESPONSE: 0 - Client 2.
                        REQUEST: 0 - Client 0.
                        RESPONSE: 0 - Client 0.
                        REQUEST: 0 - Client 1.
                        RESPONSE: 0 - Client 1.
                        REQUEST: 0 - Client 3.
                        RESPONSE: 0 - Client 3.
                        REQUEST: 1 - Client 2.
                        RESPONSE: 1 - Client 2.
                        REQUEST: 1 - Client 0.
                        RESPONSE: 1 - Client 0.
                        REQUEST: 1 - Client 1.
                        RESPONSE: 1 - Client 1.
                        REQUEST: 1 - Client 3.
                        RESPONSE: 1 - Client 3.
                        REQUEST: 2 - Client 2.
                        RESPONSE: 2 - Client 2.
                        REQUEST: 2 - Client 3.
                        RESPONSE: 2 - Client 3.
                        REQUEST: 2 - Client 1.
                        RESPONSE: 2 - Client 1.
                        REQUEST: 2 - Client 0.
                        RESPONSE: 2 - Client 0.
                        
                        ...

                        REQUEST: 8 - Client 0.
                        RESPONSE: 8 - Client 0.
                        REQUEST: 8 - Client 1.
                        RESPONSE: 8 - Client 1.
                        REQUEST: 8 - Client 2.
                        RESPONSE: 8 - Client 2.
                        REQUEST: 8 - Client 3.
                        RESPONSE: 8 - Client 3.
                        REQUEST: 9 - Client 0.
                        RESPONSE: 9 - Client 0.
                        REQUEST: 9 - Client 1.
                        RESPONSE: 9 - Client 1.
                        REQUEST: 9 - Client 3.
                        RESPONSE: 9 - Client 3.
                        REQUEST: 9 - Client 2.
                        RESPONSE: 9 - Client 2.

                        Server complete.
                    </PRE>
                  </TD>
                </TR>
              </TBODY>
            </TABLE>
          </SPAN>
        </DIV>
      </content>
    </DIV>
    <!--[if gte IE 5]><tool:tip avoidmouse="false" element="languageFilterToolTip"></tool:tip><![endif]-->
  </DIV>
</BODY></HTML>
